<?php

namespace apiend\modules\course\models;

use Yii;
use yii\db\Exception;
use yii\helpers\VarDumper;
use common\models\trade\UnifiedPayment as Trade;
use common\models\trade\TradeOrder;
use common\models\trade\HandleTrade;
use common\models\original\UserAccountLogs;
use common\helpers\Utils;
use common\models\course\Course;
use common\models\course\CourseOrder;

/**
 * 创建课程订单
 * CourseOrderForm use to buy course model.
 * 
 * @author emhome <emhome@163.com>
 * @since 1.0
 */
class CourseOrderForm extends \common\base\Model {

    /**
     * @var integer $course_id 课程ID
     */
    public $course_id;

    /**
     * @var integer $user_id 账号的UID
     */
    public $user_id;

    /**
     * @var string(16) $paymode 交易使用的支付方式 alipay|wechat
     */
    public $paymode;

    /**
     * @var integer $partner_id 类型ID
     */
    public $partner_id = 1;

    /**
     * @var 报名课程
     */
    private $_course = null;

    /**
     * 交易中心统一下单请求参数校验
     * @inheritdoc
     */
    public function rules() {
        return [
            [['paymode', 'user_id', 'course_id'], 'required'],
            ['paymode', 'in', 'range' => ['alipay', 'wechat']],
            ['course_id', 'validateCourse'],
            ['partner_id', 'safe'],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels() {
        return [
            'course_id' => '课程ID',
            'user_id' => '用户ID',
            'paymode' => '支付方式',
        ];
    }

    /**
     * Validates the APPID.
     * 验证app_id是否为该商户本身
     *
     * @param string $attribute the attribute currently being validated
     */
    public function validateCourse($attribute) {
        if (!$this->hasErrors()) {
            $course = $this->getCourse();
            if (!$course) {
                $this->addError($attribute, '课程不存在或课程报名已停止');
            } elseif (!$course->canEnroll()) {
                $this->addError($attribute, '当前课程的报名已关闭');
            }
        }
    }

    /**
     * @return \common\models\trade\Partner|null
     */
    protected function getCourse() {
        if ($this->_course === null) {
            $this->_course = Course::find()
            ->where([
                'id' => $this->course_id,
                'status' => Course::STATUS_ACTIVE
            ])
            ->one();
        }
        return $this->_course;
    }

    /**
     * Sends an email to the specified email address using the information collected by this model.
     *
     * @param string $email the target email address
     * @return bool whether the email was sent
     */
    public function save() {
        if (!$this->validate()) {
            return $this->dumpError('课程报名失败');
        }

        $course = $this->getCourse();
        if (!$course->canEnroll()) {
            return $this->dumpError('当前课程的报名已关闭');
        }

        //创建报名订单
        $order = CourseOrder::findOrNew([
            'course_id' => $this->course_id,
            'user_id' => $this->user_id,
        ]);
        if ($order->isNewRecord) {
            $order->generateOrderNo();
        }
        $bizno = $order->order_no;
        $order->price = $course->price;
        $order->discount = 0;
        $order->expired_at = $course->enroll_end_time;

        //取消当前外部订单号下的所有历史交易
        if (HandleTrade::cancelByBizno($bizno, $msg) === false) {
            Yii::error('Bizno Order cancel error:' . $msg);
            return false;
        }

        $expiretime = time() + 1800;

        //创建交易
        $trade = new Trade();
        $tradeNo = $trade->generateTn($this->paymode, $this->partner_id);
        $trade->attributes = [
            'user_id' => $this->user_id,
            'credit' => 0,
            'bizno' => $bizno,
            'unified_no' => $bizno,
            'subject' => $course->name . '课程报名',
            'body' => '【课程报名】' . $course->name,
            'expire_time' => $expiretime,
            'balance' => Trade::BALANCE_PAYMENT,
            'status' => Trade::STATUS_WAITPAY,
        ];

        //创建现金交易
        $cashOrder = new TradeOrder();
        $cashOrder->attributes = [
            'paymode' => $this->paymode,
            'currency' => TradeOrder::CURRENCY_CNY,
            'balance' => TradeOrder::BALANCE_PAYMENT,
            'original_no' => $tradeNo,
            'expire_time' => $expiretime,
            'status' => TradeOrder::STATUS_DEFAULT,
        ];
        $cashOrder->setPayType($this->paymode, $this->partner_id);
        //开启事务
        $transaction = Yii::$app->db->beginTransaction();
        try {
            if (!$order->save()) {
                throw new Exception('订单创建失败！' . Utils::arrayToString($order->errors, true));
            }
            $total = $order->price - $order->discount;
            $trade->total = $total;
            $trade->cash = $total;
            if (!$trade->save()) {
                throw new Exception('交易创建失败！' . Utils::arrayToString($trade->errors, true));
            }
            $cashOrder->pay = $total;
            $cashOrder->trade_id = $trade->id;
            if (!$cashOrder->save()) {
                throw new Exception('现金交易创建失败！' . Utils::arrayToString($cashOrder->errors, true));
            }
            $transaction->commit();
        } catch (Exception $e) {
            $transaction->rollBack();
            $msg = $e->getMessage();
            Yii::error($msg . "\n" . VarDumper::export($this->attributes), 'payment');
            return false;
        }

        //创建自动过期任务队列
//        $taskid = Yii::$app->queue->delay($this->expire_time - time())->push(new \common\jobs\TradeExpiredJob([
//            'tradeid' => $trade->id
//        ]));
//        Yii::$app->commonCache->set('queue_trade_' . $trade->id, $taskid);

        return $trade;
    }

}
